import { Helper } from "./helper";
import { types } from "./types";

export class LoopArray<T> {
  public array: T[];
  public write_pos: number;
  public length: number;
  public static New(length: number): LoopArray<number> {
    let arr = new LoopArray<number>();
    arr.array = types.number_array(length);
    arr.length = length;
    arr.write_pos = 0;
    return arr;
  }
  public Get(index: number): T {
    index += this.write_pos;
    if (index < this.length) return this.array[index];
    else return this.array[index - this.length];
  }
  public CopyTo(start: number, dst: T[], offset: number, length: number) {
    start += this.write_pos;
    if (start >= this.length) start = start - this.length;
    if (length + start > this.length) {
      Helper.ArrayCopy2(this.array, start, dst, offset, this.length - start);
      Helper.ArrayCopy2(this.array, 0, dst, offset + this.length - start, length - this.length + start);
    }
    else Helper.ArrayCopy2(this.array, start, dst, offset, length);
  }
  public PushOne(value: T) {
    this.array[this.write_pos] = value;
    this.write_pos++;
    if (this.write_pos >= this.length) {
      this.write_pos = 0;
    }
  }
  public Push(value: T, times: number) {

    if (times + this.write_pos > this.length) {
      for (var i = 0; i < this.length - this.write_pos; i++) {
        this.array[this.write_pos + i] = value;
      }
      for (var i = 0; i < times + this.write_pos - this.length; i++) {
        this.array[i] = value;
      }
      this.write_pos = times + this.write_pos - this.length;
    }
    else {
      for (var i = 0; i < times; i++) {
        this.array[this.write_pos + i] = value;
      }
      this.write_pos += times;
      if (this.write_pos == this.length) this.write_pos = 0;
    }
  }
  public PushBytes(buffer: T[], offset: number, length: number) {

    if (length + this.write_pos > this.length) {
      Helper.ArrayCopy2(buffer, offset, this.array, this.write_pos, this.length - this.write_pos);
      Helper.ArrayCopy2(buffer, offset + this.length - this.write_pos, this.array, 0, length + this.write_pos - this.length);
      this.write_pos = length + this.write_pos - this.length;
    }
    else {
      Helper.ArrayCopy2(buffer, offset, this.array, this.write_pos, length);
      this.write_pos += length;
      if (this.write_pos == this.length) this.write_pos = 0;
    }
  }
}